home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / vbcc / machines / amiga68k / libsrc / math / math_040 / cosh.s < prev    next >
Encoding:
Text File  |  1998-06-24  |  4.6 KB  |  108 lines

  1. *
  2. *   $VER: cosh.s 33.1 (23.1.97)
  3. *
  4. *   hyperbolic cosine
  5. *
  6. *   Version history:
  7. *
  8. *   33.1    23.1.97 (c) Motorola
  9. *
  10. *           - snipped from M68060SP sources
  11. *
  12.  
  13.     machine 68040
  14.     fpu     1
  15.  
  16.     XDEF    _cosh
  17.     XDEF    @cosh
  18.  
  19.     XREF    @exp
  20.  
  21. *************************************************************************
  22. * cosh():  computes the hyperbolic cosine of a normalized input         *
  23. *                                                                       *
  24. * INPUT *************************************************************** *
  25. *       fp0 = extended precision input                                  *
  26. *                                                                       *
  27. * OUTPUT ************************************************************** *
  28. *       fp0 = cosh(X)                                                   *
  29. *                                                                       *
  30. * ACCURACY and MONOTONICITY ******************************************* *
  31. *       The returned result is within 3 ulps in 64 significant bit,     *
  32. *       i.e. within 0.5001 ulp to 53 bits if the result is subsequently *
  33. *       rounded to double precision. The result is provably monotonic   *
  34. *       in double precision.                                            *
  35. *                                                                       *
  36. * ALGORITHM *********************************************************** *
  37. *                                                                       *
  38. *       COSH                                                            *
  39. *       1. If |X| > 16380 log2, go to 3.                                *
  40. *                                                                       *
  41. *       2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae      *
  42. *               y = |X|, z = exp(Y), and                                *
  43. *               cosh(X) = (1/2)*( z + 1/z ).                            *
  44. *               Exit.                                                   *
  45. *                                                                       *
  46. *       3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.            *
  47. *                                                                       *
  48. *       4. (16380 log2 < |X| <= 16480 log2)                             *
  49. *               cosh(X) = sign(X) * exp(|X|)/2.                         *
  50. *               However, invoking exp(|X|) may cause premature          *
  51. *               overflow. Thus, we calculate sinh(X) as follows:        *
  52. *               Y       := |X|                                          *
  53. *               Fact    :=      2**(16380)                              *
  54. *               Y'      := Y - 16381 log2                               *
  55. *               cosh(X) := Fact * exp(Y').                              *
  56. *               Exit.                                                   *
  57. *                                                                       *
  58. *       5. (|X| > 16480 log2) sinh(X) must overflow. Return             *
  59. *               Huge*Huge to generate overflow and an infinity with     *
  60. *               the appropriate sign. Huge is the largest finite number *
  61. *               in extended format. Exit.                               *
  62. *                                                                       *
  63. *************************************************************************
  64.  
  65. TWO16380
  66.         dc.l            $7FFB0000,$80000000,$00000000,$00000000
  67. T1      dc.l            $40C62D38,$D3D64634     ; 16381 LOG2 LEAD
  68. T2      dc.l            $3D6F90AE,$B1E75CC7     ; 16381 LOG2 TRAIL
  69.  
  70. _cosh
  71.         fmove.d         (4,sp),fp0
  72. @cosh
  73.         fmove.x         fp0,-(sp)
  74.  
  75.         move.l          (sp),d1
  76.         move.w          (4,sp),d1
  77.         and.l           #$7FFFFFFF,d1
  78.         lea             (12,sp),sp
  79.         cmp.l           #$400CB167,d1
  80.         bgt.b           .COSHBIG
  81.  
  82. ;--THIS IS THE USUAL CASE, |X| < 16380 LOG2
  83. ;--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
  84.  
  85.         fabs.x          fp0                     ; |X|
  86.  
  87.         jsr             @exp                    ; FP0 IS EXP(|X|)
  88.         fmul.s          #$3F000000,fp0          ; (1/2)EXP(|X|)
  89.  
  90.         fmove.s         #$3E800000,fp1          ; (1/4)
  91.         fdiv.x          fp0,fp1                 ; 1/(2 EXP(|X|))
  92.  
  93.         fadd.x          fp1,fp0
  94.         rts
  95.  
  96. .COSHBIG
  97.         cmp.l           #$400CB2B3,d1
  98.         bgt.b           .COSHHUGE
  99.  
  100.         fabs.x          fp0
  101.         fsub.d          (T1,pc),fp0             ; (|X|-16381LOG2_LEAD)
  102.         fsub.d          (T2,pc),fp0             ; |X| - 16381 LOG2, ACCURATE
  103.  
  104.         jsr             @exp
  105.         fmul.x          (TWO16380,pc),fp0
  106. .COSHHUGE
  107.         rts
  108.